package testObj;

import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
/**
 * @author 597983
 *
 */
public class Parse1
{
	/**
	 * @param xml : The XML String to have it's elements parsed out and stored.
	 * @param string : The file location that the formatted XML string is to be written to.
	 * @return A hashmap containing elements that have been extracted from XML.
	 * 
	 * This method will take in an XML string, take the elements, put them in an arraylist then map them to a hashmap.
	 * The reason we write the XML file is so we can store it in the database, so we have the raw file written to the disc
	 * in case we need to examine it. This method is a SAXParser, which is available for usage under the Free an Open Source
	 * software license.
	 */
	public static HashMap<String, Object> parseXML(String xml, String string) {
		
	   //The employee HashMap to be returned once the parser has ran
	   final HashMap<String,Object>Employee = new HashMap<String,Object>();
 
    try
    {
    /**
     * The SAXParserFactory defines the configuration and API for the SAX Parser.
     * The SAXParser actually created a wrapper for the java.XMLReader, giving it enhanced functionality.
     */
	SAXParserFactory factory = SAXParserFactory.newInstance();
	SAXParser saxParser = factory.newSAXParser();
	
	//The default class that handles events detected by the SAX parser
	DefaultHandler handler =new DefaultHandler()
	{
 
	/**
	 * Each one of these variables actually is meant for two things. First, there is a boolean value that is set to true anytime the
	 * tag is detected. The second is an ArrayList that we store these variables in. Together, they form the handling for each one of the
	 * specific datatypes.
	 * 
	 * BIRTHDATE = The birthdate of the employee
	 * POSTAL = The postalcode of the employee
	 * STATE = The state that the employee lives in (province, in our case.)
	 * COUNTRY = The country that the employee lives in
	 * ADDRESS1 = The primary address that the employee lives at
	 * FIRSTNAME = The employees first name
	 * LASTNAME = The employees last name
	 * EMPLID = The employees ID
	 * PHONE = The employees phone number
	 * EMAIL_ADDR = The employees Email Address
	 * 
	 * Audit Action is a different tag. This tag represents what should happen to the information within the XML. If multiple changes
	 * occur in a single XML, then the ArrayLists line up to reflect their particular Audit Action tag.
	 * 
	 * AUDIT_ACTN
	 */
	boolean BIRTHDATE = false;
	ArrayList<String>BIRTHDAY_TYPE = new ArrayList<String>();
	boolean POSTAL = false;
	ArrayList<String>POSTAL_TYPE = new ArrayList<String>();
	boolean STATE = false;
	ArrayList<String>STATE_TYPE = new ArrayList<String>();
	boolean COUNTRY = false;
	ArrayList<String>COUNTRY_TYPE = new ArrayList<String>();
	boolean ADDRESS1 = false;
	ArrayList<String>ADDRESS1_TYPE = new ArrayList<String>();
	boolean FIRSTNAME = false;
	ArrayList<String>FIRSTNAME_TYPE = new ArrayList<String>();
	boolean LASTNAME = false;
	ArrayList<String>LASTNAME_TYPE = new ArrayList<String>();
	boolean EMPLID = false;
	ArrayList<String>EMPLID_TYPE = new ArrayList<String>();
	boolean PHONE = false;
	ArrayList<String>PHONE_TYPE = new ArrayList<String>();
	boolean EMAIL_ADDR = false;
	ArrayList<String>EMAIL_ADDR_TYPE = new ArrayList<String>();
	boolean AUDIT_ACTN = false;
	ArrayList<String>AUDIT_TYPE = new ArrayList<String>();
	
 
	/* (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
	 */
	public void startElement(String uri, String localName,String qName,Attributes attributes) throws SAXException
	{
 
		System.out.println("Start Element :" + qName);
		
		//This if chain checks each tag that is processed. If the name matches the String, then the boolean flag is tripped to identify the item.
		if (qName.equalsIgnoreCase("AUDIT_ACTN"))
		{
			AUDIT_ACTN = true;
		}
		if (qName.equalsIgnoreCase("BIRTHDATE"))
		{
			BIRTHDATE = true;
		}
		if (qName.equalsIgnoreCase("POSTAL"))
		{
			POSTAL = true;
		}
		if (qName.equalsIgnoreCase("STATE"))
		{
			STATE = true;
		}
		if (qName.equalsIgnoreCase("COUNTRY"))
		{
			COUNTRY = true;
		}
		if (qName.equalsIgnoreCase("ADDRESS1"))
		{
			ADDRESS1 = true;
		}
		if (qName.equalsIgnoreCase("FIRSTNAME"))
		{
			FIRSTNAME = true;
		}
		if (qName.equalsIgnoreCase("LASTNAME"))
		{
			LASTNAME = true;
		}
		if (qName.equalsIgnoreCase("EMPLID"))
		{
			EMPLID = true;
		}
		if (qName.equalsIgnoreCase("PHONE"))
		{
			PHONE = true;
		}
		if (qName.equalsIgnoreCase("EMAIL_ADDR"))
		{
			EMAIL_ADDR = true;
		}
 
	}
 
	/* (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
	 */
	public void endElement(String uri, String localName,String qName) throws SAXException
	{
 
		System.out.println("End Element :" + qName);
 
	}
 
	/* (non-Javadoc)
	 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
	 */
	public void characters(char ch[], int start, int length) throws SAXException
	{
		/**
		 * The concept of this method is fairly straightforward. We create a string from the element found between the two tags.
		 * From there, we check to make sure this take isn't a blank, null or a newline character. If the character is good,
		 * then the boolean flag is reset and the resulting string is added to it's appropriate ArrayList.
		 * The process is the same for every step, so understanding one allows you to understand all of them.
		 */
		if (AUDIT_ACTN)
		{
			String Audit_Actn = new String(ch, start, length);
			if(Audit_Actn.equals(" ") || Audit_Actn.equals("") || Audit_Actn == null || Audit_Actn.equals("\n"))
			{
			AUDIT_ACTN = false;
			}
			else
			{
			AUDIT_TYPE.add(Audit_Actn);
			AUDIT_ACTN = false;
			Employee.put("AUDIT_ACTN",AUDIT_TYPE);
			}
		}
		if (EMPLID)
		{
			String EmplId = new String(ch, start, length);
			if(EmplId.equals(" ") || EmplId.equals("") || EmplId == null || EmplId.equals("\n"))
			{
			EMPLID = false;
			}
			else
			{
			EMPLID_TYPE.add(EmplId);
			EMPLID = false;
			Employee.put("EMPLID", EMPLID_TYPE);
			}
		}
		if (BIRTHDATE)
		{
			String birthday = new String(ch, start, length);
			if(birthday.equals(" ") || birthday.equals("") || birthday == null || birthday.equals("\n"))
			{
			BIRTHDATE = false;
			}
			else
			{
			BIRTHDAY_TYPE.add(birthday);
			BIRTHDATE = false;
			Employee.put("BIRTHDAY", BIRTHDAY_TYPE);
			}
		}
		if (POSTAL)
		{
			String postal = new String(ch, start, length);
			if(postal.equals(" ") || postal.equals("") || postal == null || postal.equals("\n"))
			{
			POSTAL = false;
			}
			else
			{
			POSTAL_TYPE.add(postal);
			POSTAL = false;
			Employee.put("POSTAL", POSTAL_TYPE);
			}
		}
 
		if (STATE)
		{
			String state = new String(ch, start, length);
			if(state.equals(" ") || state.equals("") || state == null || state.equals("\n"))
			{
			STATE = false;
			}
			else
			{
			STATE_TYPE.add(state);
			STATE = false;
			Employee.put("STATE", STATE_TYPE);
			}
			
		}
 
		if (COUNTRY)
		{
			String country = new String(ch, start, length);
			if(country.equals(" ") || country.equals("") || country == null || country.equals("\n"))
			{
			COUNTRY = false;
			}
			else
			{
			COUNTRY_TYPE.add(country);
			COUNTRY = false;
			Employee.put("COUNTRY", COUNTRY_TYPE);
			}
			
		}
		if (ADDRESS1)
		{
			String address = new String(ch, start, length);
			if(address.equals(" ") || address.equals("") || address == null || address.equals("\n"))
			{
			ADDRESS1 = false;
			}
			else
			{
			ADDRESS1_TYPE.add(address);
			ADDRESS1 = false;
			Employee.put("ADDRESS", ADDRESS1_TYPE);
			}
			
		}
		if (FIRSTNAME)
		{
			String firstName = new String(ch, start, length);
			if(firstName.equals(" ") || firstName.equals("") || firstName == null || firstName.equals("\n"))
			{
			FIRSTNAME = false;
			}
			else
			{
			FIRSTNAME_TYPE.add(firstName);
			FIRSTNAME = false;
			Employee.put("FIRSTNAME",FIRSTNAME_TYPE);
			}
			
		}
		if (LASTNAME)
		{
			String lastName = new String(ch, start, length);
			if(lastName.equals(" ") || lastName.equals("") || lastName == null || lastName.equals("\n"))
			{
			LASTNAME = false;
			}
			else
			{
			LASTNAME_TYPE.add(lastName);
			LASTNAME = false;
			Employee.put("LASTNAME", LASTNAME_TYPE);
			}
		}
		if (PHONE)
		{
			String phone = new String(ch, start, length);
			if(phone.equals(" ") || phone.equals("") || phone == null || phone.equals("\n"))
			{
			PHONE = false;
			}
			else
			{
			PHONE_TYPE.add(phone);
			PHONE = false;
			Employee.put("PHONE", PHONE_TYPE);
			}
			
		}
		if (EMAIL_ADDR)
		{
			String email = new String(ch, start, length);
			if(email.equals(" ") || email.equals("") || email == null || email.equals("\n"))
			{
			EMAIL_ADDR = false;
			}
			else
			{
			EMAIL_ADDR_TYPE.add(email);
			EMAIL_ADDR = false;
			Employee.put("EMAIL",EMAIL_ADDR_TYPE);
			}
			
		}
	}
 
     };
     // End of handler method
     /**
      * Now that all the above handler parameters have been identified, we do some tricky stuff.
      * The XmlReader.stringToDom method will take in an XML string, and return the created XML file to a specified location in the driver.
      * Once the XML file is created, the saxParser.parse method will read in the file and uses the defined handler as the rules for parsing.
      */
       XmlReader.stringToDom(xml, string);
       saxParser.parse(string, handler);
     } catch (Exception e) {
       e.printStackTrace();
     }
    //returns the employee HashMap
	return Employee; 
   } 
}